package com.bruce.tool.rpc.retry.core;

import com.bruce.tool.common.exception.BaseRuntimeException;
import com.bruce.tool.common.exception.ErrorCode;
import com.bruce.tool.rpc.retry.strateties.CustomWaitStrategy;
import com.github.rholder.retry.*;
import lombok.extern.slf4j.Slf4j;

import java.net.SocketTimeoutException;
import java.util.concurrent.ExecutionException;

/**
 * @author Bruce(刘正航)
 */
@Slf4j
public class RetryTimer {

    public <T> T whenTimeout(Behavior behavior, Long... times) {
        Retryer<T> retryer = RetryerBuilder.<T>newBuilder()
                .retryIfExceptionOfType(SocketTimeoutException.class)
                .withStopStrategy(StopStrategies.stopAfterAttempt(5))
                .withWaitStrategy(new CustomWaitStrategy(times))
                .withRetryListener(new RetryListener() {
                    @Override
                    public <V> void onRetry(Attempt<V> attempt) {
                        long attemptNumber = attempt.getAttemptNumber();
                        log.info("当前重试次数:{}", attemptNumber);
                    }
                })
                .build();
        try {
            return retryer.call(behavior.execute());
        } catch (ExecutionException e) {
            throw new BaseRuntimeException(ErrorCode.SYSTEM_ERROR, "业务异常");
        } catch (RetryException e) {
            throw new BaseRuntimeException(ErrorCode.SYSTEM_ERROR, "重试异常");
        }
    }
}
